package org.chorus;

import java.util.Timer;
import java.util.TimerTask;


import processing.core.PApplet;
import processing.core.PConstants;


//  **********************************************************************************
/** Displays a simple dynamic 'waiting' symbol with options of additional text.
 *  @author Jo Wood
 *  @version 1.0, 16th September, 2011
 */
//  **********************************************************************************

/* This file is part of the Chorus river bed analysis software package. Chorus is free software:
 * you can redistribute it and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 * 
 * Chorus is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this
 * source code (see COPYING included with this source code). If not, see 
 * http://www.gnu.org/licenses/.
 */

public class Waiter
{
	// ----------------------------- Object variables ------------------------------

	private PApplet parent;			// Sketch in which this waiter is displayed.
	private String message;			// Optional text to display.
	private int numTics;			// Number of radial tics in timer symbol.
	private int activeTic;			// The dark tick that revolves around the display
	private Timer timer;			// For scheduling the update of the dynamic waiting symbol.
	

	// ---------------------------------- Methods ----------------------------------

	/** Creates the waiter to be displayed in the given applet.
	 *  @param parent Parent applet in which this waiter will be displayed.
	 */
	public Waiter(PApplet parent)
	{
		this.parent = parent;
		message = null;
		numTics = 10;
		activeTic = 0;
		
		timer = new Timer();
		timer.scheduleAtFixedRate(new UpdateTask(), 1000, 200);
	}

	/** Draws and updates the waiting symbol and any optional text.
	 *  @param xOrigin Left-hand pixel coordinate of the area in which to draw the waiting symbol.
	 *  @param yOrigin Top pixel coordinate of the area in which to draw the waiting symbol.
	 *  @param width Width in pixels of the area in which to draw the waiting symbol.
	 *  @param height Height in pixels of the area in which to draw the waiting symbol.
	 */
	public void draw(float xOrigin, float yOrigin, float width, float height)
	{
		parent.fill(200);
		parent.noStroke();
		float outerDiam = 60;
		float innerDiam = 35;
		float cx = xOrigin + width/2;
		float cy = yOrigin + height/2;

		for (int i=0; i<numTics; i++)
		{
			parent.arc(cx,cy,outerDiam,outerDiam, PApplet.radians(i*(360/numTics)), PApplet.radians((i+0.5f)*(360/numTics)));
		}
		
		parent.fill(100);
		parent.arc(cx,cy,outerDiam,outerDiam, PApplet.radians(activeTic*(360/numTics)), PApplet.radians((activeTic+0.5f)*(360/numTics)));
		
		parent.fill(255);
		parent.ellipse(cx,cy,innerDiam,innerDiam);
		
		if (message != null)
		{
			parent.textAlign(PConstants.CENTER, PConstants.CENTER);
			parent.fill(128);
			parent.textFont(DisplayUtils.mediumFont);
			parent.text(message,cx,yOrigin+ height*0.75f);
		}
	}
	
	/** Sets the text to display. This can be changed dynamically while the waiter is showing.
	 *  @param message Text to display or null if no text is to be shown.
	 */
	public void setMessage(String message)
	{
		this.message = message;
	}
	
	/** Stops the waiter from updating. Should be called after the task that the waiter was waiting for has completed.
	 */
	public void stop()
	{
		timer.cancel();
		timer.purge();
	}
	
	
	/** Update task that updates the display at fixed intervals.
	  */
	private class UpdateTask extends TimerTask
	{
		/** Creates the new update task.
		 */
		public UpdateTask() 
		{
			// Does nothing at the moment.
		}

		/** The task that is repeated at regular intervals.
		 */
		@SuppressWarnings("synthetic-access")
		public void run() 
		{
			activeTic = (activeTic+1)%numTics;
			parent.loop();
		}
	}
}